// Date:   Tue Sep 30 08:13:03 PM 2025
// Mail:   lunar_ubuntu@qq.com
// Author: https://github.com/xiaoqixian

#pragma once

#include <utility>
#include <vector>
#include <opencv2/core.hpp>
#include "av.hpp"
#include "common.hpp"

struct FrameBase {
  int channel_id;
  int src_idx;
  long ms_ts; // frame timestamp in ms
  int label;
  int emit_seq;

  FrameBase() noexcept
    : channel_id(-1),
      // src_idx(-1),
      ms_ts(-1),
      label(-1),
      emit_seq(-1)
  {}

  // Disable copy constructor and copy assignment
  FrameBase(const FrameBase&) noexcept = default;
  FrameBase& operator=(const FrameBase&) noexcept = default;

  // Move constructor
  FrameBase(FrameBase&& other) noexcept
    : channel_id(std::exchange(other.channel_id, -1)),
      src_idx(std::exchange(other.src_idx, -1)),
      ms_ts(std::exchange(other.ms_ts, -1)),
      label(std::exchange(other.label, -1)),
      emit_seq(std::exchange(other.emit_seq, -1)) 
    {}

  // Move assignment
  FrameBase& operator=(FrameBase&& other) noexcept {
    if (this != &other) {
      channel_id = std::exchange(other.channel_id, -1);
      src_idx    = std::exchange(other.src_idx, -1);
      ms_ts      = std::exchange(other.ms_ts, -1);
      label      = std::exchange(other.label, -1);
      emit_seq   = std::exchange(other.emit_seq, -1);
    }
    return *this;
  }
};

struct Frame: FrameBase {
  cv::Mat cv_mat;

  Frame() = default;
  Frame(FrameBase const& base) noexcept
    : FrameBase(base) 
  {}
};
struct FramePkts: FrameBase {
  std::vector<AVPacketWrapper> inter_pkts;
};
struct ActionShot: Frame {
  long shot_ms;

  template <typename U>
  ActionShot(U&& frame):
    Frame(std::forward<U>(frame)),
    shot_ms(now_ms())
  {}
};

